#include <errno.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include "freebsd_write_file_range.h"
#include "http_server.h"

int freebsd_write_file_range (http_connection_t *http_connection, off_t to)
{
	/* Return values:
	 * -1: Error.
	 *  0: Send has been interrupted.
	 *  1: Range has been sent.
	 */

	size_t nbytes;
	off_t sbytes;

	do {
		nbytes = to - http_connection->offset + 1;
		sbytes = 0;

		if (sendfile (http_connection->fd, http_connection->sd, http_connection->offset, nbytes, NULL, &sbytes, 0) < 0) {
			if (errno == EAGAIN) {
				if (sbytes > 0) {
					http_connection->last_read_write = http_server.current_time;

					http_connection->sent += sbytes;
					http_connection->offset += sbytes;
				} else {
					return 0;
				}
			} else if (errno == EINTR) {
				/* A signal occurred before any data was transmitted. */
				/* Add ourself to the list of interrupted HTTP connections. */
				http_server.interrupted_http_connections[http_server.number_interrupted_http_connections++] = http_connection;

				return 0;
			} else {
				return -1;
			}
		} else {
			http_connection->last_read_write = http_server.current_time;

			http_connection->sent += nbytes;
			http_connection->offset += nbytes;

			if (http_connection->offset >= to + 1) {
				/* We are done. */
				return 1;
			}
		}
	} while (1);
}
